# -*- coding: utf-8 -*-

import json

from django.utils.decorators import method_decorator
from django.utils.encoding import smart_unicode
from django.views.decorators.http import require_GET, require_POST
from django.views.generic import TemplateView

from common.admin import db as user_db
from common.admin.model import ROLE
from common.level_strategy import db as level_db
from common.mch import admin_db as mch_db
from common.mch.admin_db import SERVICE_MAP
from common.utils import track_logging
from common.utils.api import token_required
from common.utils.decorator import response_wrapper
from common.utils.exceptions import Error, ParamError
from common.utils.tz import (
    utc_to_local_str
)

_LOGGER = track_logging.getLogger(__name__)


class MchView(TemplateView):
    def get(self, req):
        query_dct = req.GET.dict()
        cond = user_db.get_mchids_filter_by_user(req.user_id)
        _LOGGER.info('MchView get cond: %s, ', cond)
        if cond and not query_dct.get('id', ''):
            query_dct['id'] = cond
        _LOGGER.info('MchView get mchs: %s, ', query_dct)

        items, total_count = mch_db.list_mch(query_dct)

        resp_items = []
        for item in items:
            data = item.as_dict()
            data['created_at'] = utc_to_local_str(data['created_at'])
            data['updated_at'] = utc_to_local_str(data['updated_at'])
            resp_items.append(data)

        return {'list': resp_items, 'page': query_dct.get('$page', 1),
                'size': len(resp_items), 'total_count': total_count}

    def post(self, req):
        param_dct = json.loads(req.body)
        mch = mch_db.create_mch(param_dct)
        service_conf = param_dct.pop('service_conf', {})
        for service_name, conf in service_conf.items():
            chns = [str(i) for i in conf['chns']]
            mch_db.upsert_mch_chn({
                'mch_id': mch.id,
                'service_name': service_name,
                'chns': ','.join(chns),
                'notify_prefix': conf['notify_prefix'],
            }, mch.id, service_name)
        return {}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(MchView, self).dispatch(*args, **kwargs)


def _check_conf(query_dct):
    service_conf = query_dct.get('service_conf', {})
    result = True
    msg = u'上分通道不能为空'
    for service_name, conf in service_conf.items():
        chns = [str(i) for i in conf['chns']]
        if service_name == 'withdraw_alipay' and len(chns) == 0:
            return True, u'下分通道不能为空'
        if len(chns) > 0 and service_name != 'withdraw_alipay':
            result = False
            msg = 'success'
    return result, msg


class SingleMchView(TemplateView):
    def get(self, req, mch_id):
        mch = mch_db.get_mch(id=int(mch_id))
        mch_chn_items, total_count = mch_db.list_mch_chn({'mch_id': mch_id})
        service_conf = {}
        for item in mch_chn_items:
            data = item.as_dict()
            service_conf.update({
                item.service_name: {
                    'chns': [] if not item.chns else item.chns.split(','),
                    'notify_prefix': item.notify_prefix
                }
            })
        data = mch.as_dict()
        data['service_conf'] = service_conf
        data['created_at'] = utc_to_local_str(data['created_at'])
        data['updated_at'] = utc_to_local_str(data['updated_at'])
        data['user_level_strategy_id'] = level_db.get_user_level_strategy_by_mch_id(int(mch_id))
        return data

    def post(self, req, mch_id):
        return self.put(req, mch_id)

    def put(self, req, mch_id):
        query_dct = json.loads(smart_unicode(req.body))
        result, msg = _check_conf(query_dct)
        if result:
            raise Error(msg=msg, httpcode=200)
        mch_db.upsert_mch(query_dct, int(mch_id))
        service_conf = query_dct.pop('service_conf', {})
        for service_name, conf in service_conf.items():
            chns = [str(i) for i in conf['chns']]
            mch_db.upsert_mch_chn({
                'mch_id': mch_id,
                'service_name': service_name,
                'chns': ','.join(chns),
                'notify_prefix': conf['notify_prefix'],
            }, mch_id, service_name)
        return {}

    def patch(self, req, mch_id):
        query_dct = json.loads(smart_unicode(req.body))
        for service_type in SERVICE_MAP:
            if service_type in query_dct:
                query_dct[service_type] = list(set(query_dct[service_type]))
        mch_db.upsert_mch(query_dct, int(mch_id))
        mch_db.modify_mch_chn(query_dct, int(mch_id))
        return {}

    def delete(self, req, mch_id):
        if req.user.role != ROLE.ADMIN:
            raise ParamError(u'只有管理员才能删除通道')
        mch_db.delete_mch(int(mch_id))
        _LOGGER.info('delete mch: %s, user: %s', mch_id, req.user_id)
        return {}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(SingleMchView, self).dispatch(*args, **kwargs)


@require_GET
@response_wrapper
@token_required
def get_mch_detail(req, mch_id):
    mch = mch_db.get_mch(id=int(mch_id))
    mch_chn_items, total_count = mch_db.list_mch_chn({'mch_id': mch_id})
    data = mch.as_dict()
    data['created_at'] = utc_to_local_str(data['created_at'])
    data['updated_at'] = utc_to_local_str(data['updated_at'])
    data['user_level_strategy_id'] = level_db.get_user_level_strategy_by_mch_id(int(mch_id))
    for item in mch_chn_items:
        t = item.chns
        tmp = []
        if t:
            for c in t.split(','):
                tmp.append(int(c))
        data[item.service_name] = tmp
    return data


@require_POST
@response_wrapper
@token_required
def modify_mch(req, mch_id):
    query_dct = json.loads(smart_unicode(req.body))
    mch_db.upsert_mch(query_dct, int(mch_id))
    service_conf = query_dct.pop('service_conf', {})
    for service_name, conf in service_conf.items():
        chns = [str(i) for i in conf['chns']]
        mch_db.upsert_mch_chn({
            'mch_id': mch_id,
            'service_name': service_name,
            'chns': ','.join(chns),
            'notify_prefix': conf['notify_prefix'],
        }, mch_id, service_name)
    return {}
